<?php 
namespace PsiFramework\Classes\Util\Parameters\DAO;

import("Classes.Util.Parameters.Parameters");
import("Classes.Util.Parameters.Action.ActionMapping");
import("Classes.Util.Parameters.DAO.ActionMappingDAO");
import("Classes.Util.Parameters.DAO.ServiceMappingDAO");
import("Classes.Util.Parameters.DAO.ParametersDAO");
import("Classes.Util.Manager.ObjectManager");

use \PsiFramework\Classes\Util\Parameters\Parameters;
use \PsiFramework\Classes\Util\Parameters\Action\ActionMapping;
use \PsiFramework\Classes\Util\Parameters\DAO\ActionMappingDAO;
use \PsiFramework\Classes\Util\Parameters\DAO\ObjectParametersDAO;
use \PsiFramework\Classes\Util\Parameters\DAO\ParametersDAO;
use \PsiFramework\Classes\Util\Parameters\DAO\ServiceMappingDAO;
use \PsiFramework\Classes\Util\Manager\ObjectManager;

/**
 * PsiFramework
 * Php Simple Framework
 *
 * @author Rémi San
 * @version beta
 */

/**
 * The ConfigDAO class is the generic class to retrieve
 * application or plugin parameters
 *
 * @package Util.Parameters.DAO
 */
class ConfigDAO
{

    protected /*DomElement*/   $_racine ;
    protected /*string*/       $_parentName ;
    protected /*string*/       $_file ;

    public function __construct()
    {
        $this->_racine = null ;
        $this->_parentName = null ;
        $this->_file = null ;
    }

    public function init(\DomElement $racine)
    {
        $this->_racine = $racine ;
    }

    public function initByFile(/*string*/ $file)
    {
        $this->_file = $file ;
        $document = new \DomDocument();
        $document->load($file);
        $this->_racine = $document->documentElement;
    }

    public function getParentName()
    {
        return $this->_parentName ;
    }

    protected function retrieve()
    {

        $vars = array();

        //Name
        $name = $this->_racine->getAttribute("name");
        $vars['name'] = $name ;

        //Parent
        $parentName = $this->_racine->getAttribute("parent");
        if (!isNullOrEmptyString($parentName)) {
            $this->_parentName = $parentName ;
        }

        //Objects
        $parametersDao = ObjectParametersDAO::getInstance();
        $objectParameters = array();
        $objectsArray
            = $this->_racine->getElementsByTagName("objects")->item(0);
        if (!is_null($objectsArray)) {
            $links = $objectsArray->getElementsByTagName("link");
            if (!is_null($links)) {
                foreach ($links as $link) {
                    $filePath = $link->getAttribute('path');
                    if (startsWith($filePath, './') && !is_null($this->_file)) {
                        $basePath = substr(
                            $this->_file,
                            0,
                            strrpos($this->_file, '/')
                        );
                        $filePath = $basePath .'/' . substr($filePath, 2);
                    }
                    $object = $parametersDao->read(
                        ParametersDAO::getDocumentRoot($filePath)
                    );
                    if (!is_null($object)) {
                        $objectParameters[$object->getName()] = $object ;
                        ObjectManager::getInstance()->addObject(
                            $object->getName()
                        );
                    }
                }
            }
            $objects = $objectsArray->getElementsByTagName("object");
            if (!is_null($objects)) {
                foreach ($objects as $obj) {
                    $object = $parametersDao->read($obj);
                    if (!is_null($object)) {
                        $objectParameters[$object->getName()] = $object ;
                        ObjectManager::getInstance()->addObject(
                            $object->getName()
                        );
                    }
                }
            }
            $primitiveObjects = $objectsArray->getElementsByTagName(
                "primitive_object"
            );
            if (!is_null($primitiveObjects)) {
                foreach ($primitiveObjects as $obj) {
                    ObjectManager::getInstance()->addPrimitiveObject(
                        $obj->getAttribute("name"),
                        $obj->getAttribute("class"),
                        $obj->getAttribute("dao")
                    );
                }
            }
        }
        $vars['objectParameters'] = $objectParameters ;

        //Action-Mapping
        $actionMappingDao = new ActionMappingDAO();
        $actionMappingElement = $this->_racine
            ->getElementsByTagName("action-mapping")
            ->item(0);
        $actionMapping = null ;
        if (!is_null($actionMappingElement)) {
            $actionMappingDao->init($actionMappingElement);
            $actionMapping = $actionMappingDao->readActionMapping();
        }
        $vars['actionMapping'] = $actionMapping ;

        //Services
        $servicesElements = $this->_racine->getElementsByTagName("services");
        $serviceMappingDao = new ServiceMappingDAO();
        $serviceMappingElement = $this->_racine
            ->getElementsByTagName("services")
            ->item(0);
        $servicesParameters = null ;
        if (!is_null($serviceMappingElement)) {
            $serviceMappingDao->init($serviceMappingElement);
            $servicesParameters = $serviceMappingDao->readServiceMapping();
        }
        $vars['servicesParameters'] = $servicesParameters ;

        //Parameters
        $parametersDao = ParametersDAO::getInstance();
        $parametersRoot = $this->_racine
            ->getElementsByTagName("parameters")
            ->item(0);
        $parameters = null ;
        if ($parametersRoot != null) {
            $parameters = new Parameters($parametersDao->read($parametersRoot));
        }
        $vars['parameters'] = $parameters ;

        return $vars ;
    }
}
